package com.rainszj.service.impl;

import com.rainszj.mapper.CommentMapper;
import com.rainszj.pojo.po.Comment;
import com.rainszj.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 处理评论业务逻辑
 *
 * @author rainszj
 * 2020/3/21
 */
@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentMapper commentMapper;

    /**
     * 存放一级评论的所有子代的集合
     */
    private List<Comment> replyComments = new ArrayList<>();

    /**
     * 将所有一级评论以下的内容存储到对应 一个replyComments
     * 只实现二级回复的效果
     *
     * @param blogId 一个博客对应一个 List集合的评论
     * @return
     */
    @Override
    public List<Comment> listCommentByBlogId(Long blogId) {
        List<Comment> comments = commentMapper.listCommentByBlogId(blogId);
        for (Comment comment : comments) {
            // 查询并设置顶级评论的回复信息
            comment.setReplyComments(commentMapper.queryChildComments(comment.getId()));
            // 获取当前节点的回复信息 二级回复信息
            List<Comment> subComments = comment.getReplyComments();
            for (Comment subComment : subComments) {
                // 设置当前子节点的子回复信息，也就是三级回复信息
                subComment.setReplyComments(commentMapper.queryChildComments(subComment.getId()));
                // 添加到 存储所有非顶级节点的 replyComments 中
                replyComments.add(subComment);
                // 递归添加
                recursively(subComment);
            }
            // 存放非顶级节点下的所有评论
            comment.setReplyComments(replyComments);
            // 将当前引用指向一个新的引用，不能使用 clear，会将comment中设置的回复信息清 0
            replyComments = new ArrayList<>();
        }
        // 设置子级中的父级对应的 昵称
        setParentNickname(comments);
        return comments;
    }


    /**
     * @param comments root根节点，blog不为空的对象集合
     * @return
     */
    private void combineChildren(List<Comment> comments) {

        for (Comment comment : comments) {
            List<Comment> replys1 = comment.getReplyComments();
            for (Comment reply1 : replys1) {
                reply1.setReplyComments(commentMapper.queryChildComments(reply1.getId()));
                //循环迭代，找出子代，存放在tempReplys中
                recursively(reply1);
            }
            //修改顶级节点的reply集合为迭代处理后的集合
            comment.setReplyComments(replyComments);
            //清除临时存放区
            replyComments = new ArrayList<>();
        }
    }


    /**
     * 递归迭代，剥洋葱
     *
     * @param comment 被迭代的对象
     * @return
     */
    private void recursively(Comment comment) {
        if (comment.getReplyComments().size() > 0) {
            List<Comment> replys = comment.getReplyComments();
            for (Comment reply : replys) {
                reply.setReplyComments(commentMapper.queryChildComments(reply.getId()));
                replyComments.add(reply);
                if (reply.getReplyComments().size() > 0) {
                    recursively(reply);
                }
            }
        }
    }

    /**
     * 保存评论
     *
     * @param comment
     * @return
     */
    @Override
    public int saveComment(Comment comment) {


        Long parentCommentId = comment.getParentCommentId();
        if (parentCommentId != -1) {
            // 有父级评论
            comment.setParentComment(commentMapper.queryParentComment(parentCommentId));
        } else {
            comment.setParentComment(null);
        }

        comment.setCreateTime(new Date());

        return commentMapper.saveComment(comment);
    }


    /**
     * 通过父级 Id 设置子级中 parentComment的 nickname
     *
     * @param comments
     */
    private void setParentNickname(List<Comment> comments) {
        for (Comment comment : comments) {
            List<Comment> replys = comment.getReplyComments();
            for (Comment reply : replys) {
                if (reply.getParentCommentId() != null) {
                    Comment parent = commentMapper.queryParentNicknameById(reply.getParentCommentId());
                    Comment c = new Comment();
                    c.setNickname(parent.getNickname());
                    reply.setParentComment(c);
                }
            }
        }
    }
}